package Utils.Aspect;

import annotation.Bean;
import annotation.Before;
import component.Ioc;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class AspectFactory {
    static Class<?> klass;
    static Method method;
    static Ioc ioc = Ioc.getIoc();
    public static void solve(String filePath,Class<?> klass1,Method method1) throws ClassNotFoundException, NoSuchMethodException {
        klass = klass1;
        method = method1;
        String[] strings = filePath.split("\\.");
        strings[strings.length-1] += ".class";
        findClass(strings,"",0);
    }
    private static void findClass(String[] strings,String filePath,int pos) throws ClassNotFoundException, NoSuchMethodException {
        if (pos>=strings.length) {
            if (filePath.endsWith(".class")) create(filePath);
            return;
        }
        filePath+="/";
        File file = new File(AspectFactory.class.getResource(filePath).getPath());
        String[] names = file.list();
        if (names == null) return;
        for (String str: names){
            if(strings[pos].equals("*.class") ||strings[pos].equals(str))findClass(strings, filePath+str,pos+1);
        }

    }
    private static void create(String filepath) throws ClassNotFoundException, NoSuchMethodException {
        Enhancer enhancer = new Enhancer();
        filepath = filepath.substring(1,filepath.length()-6).replaceAll("/",".");
        enhancer.setSuperclass(Class.forName(filepath));
        enhancer.setCallback(new MethodInterceptor() {
            @Override
            public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                before();
                System.out.println(o.getClass());
                methodProxy.invokeSuper(o, objects);
                return methodProxy;
            }
        });
        Object o =  enhancer.create();
        Class<?> kla = Class.forName(filepath);
        System.out.println(kla);
        if(klass.getAnnotation(Bean.class) != null){
            String alise = klass.getDeclaredAnnotation(Bean.class).Alise();
            boolean Sington = klass.getAnnotation(Bean.class).SingleTon();
            if (alise == null || alise == "" || alise.isEmpty()){
                String[] names = filepath.split("\\.");
                alise = names[names.length-1];
            }
            if(Sington == false){ //多例模式，保存全类名，方便反射生成
                ioc.insertFactoryBean(alise,filepath);
                return;
            }
            System.out.println(alise);
            ioc.insertFactoryBean(alise,o);
        }
    }
    public static void before() throws InvocationTargetException, IllegalAccessException, InstantiationException {
        if (method.getDeclaredAnnotation(Before.class) != null){
            method.invoke(klass.newInstance());
        }
    }
}
